package com.github.ecbp.store.service.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.ecbp.common.data.entity.BaseEntity;
import com.github.ecbp.common.data.service.impl.BaseServiceImpl;
import com.github.ecbp.common.data.utils.TransformUtils;
import com.github.ecbp.common.utils.Asserts;
import com.github.ecbp.store.service.common.StoreCodeAndMessageEnum;
import com.github.ecbp.store.service.dto.CouponDTO;
import com.github.ecbp.store.service.entity.Coupon;
import com.github.ecbp.store.service.entity.CouponProductCategoryRelation;
import com.github.ecbp.store.service.entity.CouponProductRelation;
import com.github.ecbp.store.service.mapper.CouponMapper;
import com.github.ecbp.store.service.mapper.CouponProductCategoryRelationMapper;
import com.github.ecbp.store.service.mapper.CouponProductRelationMapper;
import com.github.ecbp.store.service.service.CouponService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;

import static com.github.ecbp.store.service.constant.StoreServiceConstant.COUPON_USE_IN_PRODUCT;
import static com.github.ecbp.store.service.constant.StoreServiceConstant.COUPON_USE_IN_PRODUCT_CATEGORY;

/**
 * @Author Created by Alex·He on 2020/5/29 9:58
 * @Version 1.0
 * @Description 优惠卷表(Coupon)表服务实现类
 */
@Service
public class CouponServiceImpl extends BaseServiceImpl<CouponMapper, Coupon> implements CouponService {
    @Autowired
    private CouponProductCategoryRelationMapper couponProductCategoryRelationMapper;
    @Autowired
    private CouponProductRelationMapper couponProductRelationMapper;

    /**
     *功能描述：
     * @author Created by Alex·He on 2020/5/29 11:40
     * @version 1.0
     * @description 保存优惠卷
     */
    @Override
    public boolean save(CouponDTO param) {
        Coupon coupon = TransformUtils.copy(param, Coupon.class);
        Asserts.checkNotNull(coupon, StoreCodeAndMessageEnum.COUPON_NOT_EXISTS_ERROR);
        // 保存优惠卷信息
        Asserts.checkHandle(baseMapper.insert(coupon), StoreCodeAndMessageEnum.COUPON_SAVE_ERROR);
        // 获取优惠券的使用范围
        Integer useRange = param.getUseRange();
        // 优惠券在指定分类中使用，则建立优惠券与商品分类的关系
        if (useRange.equals(COUPON_USE_IN_PRODUCT_CATEGORY)) {
            for (Long categoryId : param.getProductCategoryIds()) {
                CouponProductCategoryRelation relation = new CouponProductCategoryRelation();
                relation.setCouponId(coupon.getId());
                relation.setProductCategoryId(categoryId);;
                Asserts.checkHandle(couponProductCategoryRelationMapper.insert(relation),
                        StoreCodeAndMessageEnum.COUPON_PRODUCT_CATEGORY_REL_SAVE_ERROR);
            }
        }
        // 优惠券在指定商品中使用，则建立优惠券与商品的关系
        if (useRange.equals(COUPON_USE_IN_PRODUCT)) {
            for (Long productId : param.getProductIds()) {
                CouponProductRelation relation = new CouponProductRelation();
                relation.setCouponId(coupon.getId());
                relation.setProductId(productId);
                Asserts.checkHandle(couponProductRelationMapper.insert(relation),
                        StoreCodeAndMessageEnum.COUPON_PRODUCT_REL_SAVE_ERROR);
            }
        }
        return true;
    }

    /**
     *功能描述：
     * @author Created by Alex·He on 2020/5/29 16:01
     * @version 1.0
     * @description 删除优惠卷
     */
    @Override
    public boolean removeById(Long id) {
        // 删除优惠券与商品分类的关系
        deleteCouponProductCategoryRelation(id);
        // 删除优惠券与商品的关系
        deleteCouponProductRelation(id);
        LambdaQueryWrapper<Coupon> wrapper = new LambdaQueryWrapper<>(Coupon.class);
        wrapper.eq(Coupon::getId, id);
        Asserts.checkHandle(baseMapper.deleteWithFill(new Coupon(), wrapper), StoreCodeAndMessageEnum.COUPON_DELETE_ERROR);
        return true;
    }

    /**
     *功能描述：
     * @author Created by Alex·He on 2020/5/29 16:01
     * @version 1.0
     * @description 批量删除优惠卷
     */
    @Override
    public boolean removeByIds(List<Long> ids) {
        // TODO 需优化
        for (Long id : ids) {
            // 删除优惠券与商品分类的关系
            deleteCouponProductCategoryRelation(id);
            // 删除优惠券与商品的关系
            deleteCouponProductRelation(id);
            LambdaQueryWrapper<Coupon> wrapper = new LambdaQueryWrapper<>(Coupon.class);
            wrapper.eq(Coupon::getId, id);
            Asserts.checkHandle(baseMapper.deleteWithFill(new Coupon(), wrapper), StoreCodeAndMessageEnum.COUPON_DELETE_ERROR);
        }
        return true;
    }

    /**
     *功能描述：
     * @author Created by Alex·He on 2020/6/1 9:49
     * @version 1.0
     * @description 更新优惠卷
     */
    @Override
    public boolean updateById(CouponDTO param) {
        Coupon coupon = TransformUtils.copy(param, Coupon.class);
        Asserts.checkNotNull(coupon, StoreCodeAndMessageEnum.COUPON_NOT_EXISTS_ERROR);
        // 更新优惠卷信息
        Asserts.checkHandle(baseMapper.updateById(coupon), StoreCodeAndMessageEnum.COUPON_SAVE_ERROR);
        // 获取优惠券的使用范围
        Integer useRange = param.getUseRange();
        // 优惠券在指定分类中使用，则建立优惠券与商品分类的关系
        if (useRange.equals(COUPON_USE_IN_PRODUCT_CATEGORY)) {
            // 删除优惠券与商品分类的关系
            deleteCouponProductCategoryRelation(param.getId());
            for (Long categoryId : param.getProductCategoryIds()) {
                CouponProductCategoryRelation relation = new CouponProductCategoryRelation();
                relation.setCouponId(coupon.getId());
                relation.setProductCategoryId(categoryId);;
                Asserts.checkHandle(couponProductCategoryRelationMapper.insert(relation),
                        StoreCodeAndMessageEnum.COUPON_PRODUCT_CATEGORY_REL_SAVE_ERROR);
            }
        }
        // 优惠券在指定商品中使用，则建立优惠券与商品的关系
        if (useRange.equals(COUPON_USE_IN_PRODUCT)) {
            // 删除优惠券与商品的关系
            deleteCouponProductRelation(param.getId());
            for (Long productId : param.getProductIds()) {
                CouponProductRelation relation = new CouponProductRelation();
                relation.setCouponId(coupon.getId());
                relation.setProductId(productId);
                Asserts.checkHandle(couponProductRelationMapper.insert(relation),
                        StoreCodeAndMessageEnum.COUPON_PRODUCT_REL_SAVE_ERROR);
            }
        }
        return true;
    }

    /**
     *功能描述：
     * @author Created by Alex·He on 2020/5/29 16:30
     * @version 1.0
     * @description 删除优惠券与商品分类的关系
     */
    private void deleteCouponProductCategoryRelation(Long couponId) {
        LambdaQueryWrapper<CouponProductCategoryRelation> wrapper = new LambdaQueryWrapper<>(CouponProductCategoryRelation.class);
        wrapper.eq(CouponProductCategoryRelation::getCouponId, couponId);
        // TODO 需优化
        couponProductCategoryRelationMapper.deleteWithFill(new CouponProductCategoryRelation(), wrapper);
//        Asserts.checkHandle(couponProductCategoryRelationMapper.deleteWithFill(new CouponProductCategoryRelation(), wrapper),
//                StoreCodeAndMessageEnum.COUPON_PRODUCT_CATEGORY_REL_DELETE_ERROR);
    }

    /**
     *功能描述：
     * @author Created by Alex·He on 2020/5/29 16:34
     * @version 1.0
     * @description 删除优惠券与商品的关系
     */
    private void deleteCouponProductRelation(Long couponId) {
        LambdaQueryWrapper<CouponProductRelation> wrapper = new LambdaQueryWrapper<>(CouponProductRelation.class);
        wrapper.eq(CouponProductRelation::getCouponId, couponId);
        // TODO 需优化
        couponProductRelationMapper.deleteWithFill(new CouponProductRelation(), wrapper);
//        Asserts.checkHandle(couponProductRelationMapper.deleteWithFill(new CouponProductRelation(), wrapper),
//                StoreCodeAndMessageEnum.COUPON_PRODUCT_REL_DELETE_ERROR);
    }

    @Override
    protected void assemble(Coupon entity, LambdaQueryWrapper<Coupon> wrapper) {
        super.assemble(entity, wrapper);
        if (!StringUtils.isEmpty(entity.getName())) {
            wrapper.likeRight(Coupon::getName, entity.getName());
        }
        if (!StringUtils.isEmpty(entity.getOrigin())) {
            wrapper.likeRight(Coupon::getOrigin, entity.getOrigin());
        }
        if (!StringUtils.isEmpty(entity.getUseRange())) {
            wrapper.likeRight(Coupon::getUseRange, entity.getUseRange());
        }
        if (!StringUtils.isEmpty(entity.getPlatform())) {
            wrapper.likeRight(Coupon::getPlatform, entity.getPlatform());
        }
        if (!StringUtils.isEmpty(entity.getEnableTime())) {
            wrapper.likeRight(Coupon::getEnableTime, entity.getEnableTime());
        }
        if (!StringUtils.isEmpty(entity.getStartTime())) {
            wrapper.likeRight(Coupon::getStartTime, entity.getStartTime());
        }
        if (!StringUtils.isEmpty(entity.getEndTime())) {
            wrapper.likeRight(Coupon::getEndTime, entity.getEndTime());
        }
        wrapper.orderByDesc(BaseEntity::getCreateTime);
    }
}
